import '../models/question_model.dart';
import '../models/exam_model.dart';
import 'excel_import_service.dart';
import 'package:flutter/foundation.dart';
import 'dart:io';
import 'dart:math';
import 'package:path_provider/path_provider.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

class ExamService {
  static const String _examsDataKey = 'exams_data';
  
  // 存储所有考试
  static final List<Exam> _exams = [];
  // 存储所有考试结果
  static final Map<String, List<ExamResult>> _examResults = {};
  // 存储已分配的考试ID和学生ID的映射关系
  static final Map<String, Set<String>> _assignedExams = {};
  // 最近分配的试卷记录（用于避免相邻学生分配相同试卷）
  static String? _lastAssignedExamId;
  static bool _isInitialized = false;
  
  // 初始化考试服务
  static Future<void> init() async {
    if (_isInitialized) return;
    
    try {
      // 从本地存储加载考试数据
      await _loadExamsFromStorage();
      // 从本地存储加载考试结果
      await _loadExamResultsFromStorage();
      await _loadAssignedExamsFromStorage();
      _isInitialized = true;
      debugPrint('考试服务初始化完成，加载了 ${_exams.length} 个考试');
    } catch (e) {
      debugPrint('初始化考试服务失败: $e');
    }
  }
  
  // 获取所有考试
  static List<Exam> getAllExams() {
    return List.from(_exams);
  }
  
  // 获取指定ID的考试
  static Exam? getExamById(String id) {
    try {
      return _exams.firstWhere((exam) => exam.id == id);
    } catch (e) {
      return null;
    }
  }
  
  // 添加新考试（带去重逻辑，考虑试卷ID和序号）
  static Future<void> addExam(Exam exam) async {
    // 检查是否已存在相同ID的考试（现在ID是稳定的，基于originalId和sequence生成）
    final existingIndex = _exams.indexWhere((e) => e.id == exam.id);

    if (existingIndex >= 0) {
      final existingExam = _exams[existingIndex];

      // 检查考试内容是否真的相同（题目数量、总分、时长）
      final isSameContent = existingExam.questions.length == exam.questions.length &&
                           existingExam.totalScore == exam.totalScore &&
                           existingExam.duration == exam.duration;

      if (isSameContent) {
        // 内容相同，保持原有考试不变，避免破坏数据关联
        debugPrint('考试 ${exam.title} (ID: ${exam.id}) 已存在且内容相同，跳过更新以保持数据关联');
        return; // 不保存，直接返回
      } else {
        // 内容不同，说明试卷被修改了，需要更新
        _exams[existingIndex] = exam;
        debugPrint('考试 ${exam.title} (ID: ${exam.id}) 内容已更新');
      }
    } else {
      // 如果不存在，添加新考试
      _exams.add(exam);
      debugPrint('考试 ${exam.title} (ID: ${exam.id}) 已添加');
    }

    // 保存到本地存储
    await _saveExamsToStorage();
  }
  
  // 根据固定路径创建考试 - 返回空实现
  static Future<Exam?> createExamFromFixedPath() async {
    debugPrint('此方法已废弃，请使用createExamFromExcelFile');
    return null;
  }
  
  // 计算题目总分
  static double calculateTotalScore(List<Question> questions) {
    double total = 0;
    for (var question in questions) {
      total += question.score;
    }
    return total;
  }
  
  // 生成示例模板并保存到固定路径
  static Future<String?> generateAndSaveTemplate() async {
    return ExcelImportService.createAndSaveExcelTemplate();
  }
  
  static Future<void> _saveExam(Exam exam) async {
    // 将考试添加到内存中的列表
    _exams.add(exam);
    
    // 这里可以添加持久化存储逻辑，例如保存到本地存储或数据库
    // 目前仅添加到内存列表中，实际应用中应该实现持久化
    print('考试 ${exam.title} 已保存，共 ${exam.questions.length} 道题');
    
    // 模拟网络延迟
    await Future.delayed(const Duration(milliseconds: 500));
    
    return;
  }
  
  // 导出Excel题目模板
  static Future<String?> exportQuestionTemplate() async {
    return ExcelImportService.createAndSaveExcelTemplate();
  }

  // 考试评分逻辑（客观题） 
  static Map<String, int> gradeObjectiveQuestions(Exam exam, ExamResult result) {
    Map<String, int> scores = {};
    Map<String, dynamic> answers = result.answers;
    
    for (var question in exam.questions) {
      String questionId = question.id;
      
      // 检查答案是否存在
      bool hasTextAnswer = answers.containsKey(questionId);
      bool hasPhotoAnswers = result.answerImages.containsKey(questionId) && 
                             result.answerImages[questionId]!.isNotEmpty;
      
      if (!hasTextAnswer && !hasPhotoAnswers) {
        scores[questionId] = 0;
        continue;
      }
      
      dynamic userAnswer = hasTextAnswer ? answers[questionId] : null;
      
      switch (question.type) {
        case QuestionType.singleChoice:
          var q = question as SingleChoiceQuestion;
          // 单选题答案是选项ID (字符串)
          String selectedOptionId = userAnswer is String ? userAnswer : "";
          // 获取正确选项ID
          String correctOptionId = q.choices.length > q.correctOption ? q.choices[q.correctOption].id : "";
          scores[questionId] = selectedOptionId == correctOptionId ? q.score : 0;
          break;
          
        case QuestionType.multipleChoice:
          var q = question as MultipleChoiceQuestion;
          // 多选题答案是选项ID数组 (字符串数组)
          List<String> selectedOptionIds = [];
          if (userAnswer is List) {
            selectedOptionIds = List<String>.from(userAnswer.map((e) => e.toString()));
          }
          
          // 获取正确选项ID列表
          List<String> correctOptionIds = [];
          for (var i in q.correctOptions) {
            if (i >= 0 && i < q.choices.length) {
              correctOptionIds.add(q.choices[i].id);
            }
          }
          
          // 检查答案是否完全匹配
          bool allCorrect = correctOptionIds.length == selectedOptionIds.length &&
                           correctOptionIds.every((opt) => selectedOptionIds.contains(opt));
          scores[questionId] = allCorrect ? q.score : 0;
          break;
          
        case QuestionType.fillBlank:
          var q = question as FillBlankQuestion;

          if (q.isMultiBlank) {
            // 多空填空题处理
            List<String> userAnswers = [];
            if (userAnswer is List) {
              userAnswers = userAnswer.map((e) => e?.toString().trim() ?? '').toList();
            } else if (userAnswer is String) {
              // 如果存储为字符串（逗号分隔），则分解
              userAnswers = userAnswer.split(',').map((e) => e.trim()).toList();
            }

            // 确保答案数量匹配
            while (userAnswers.length < q.blankCount) {
              userAnswers.add('');
            }

            // 逐个比较每个空的答案
            int correctCount = 0;
            for (int i = 0; i < q.blankCount && i < q.correctAnswers.length; i++) {
              String userAns = i < userAnswers.length ? userAnswers[i].toLowerCase() : '';
              String correctAns = q.correctAnswers[i].toLowerCase();
              if (userAns == correctAns) {
                correctCount++;
              }
            }

            // 计算得分：按正确空的比例给分
            double scoreRatio = correctCount / q.blankCount;
            scores[questionId] = (q.score * scoreRatio).round();

            debugPrint('多空填空题评分: 题目=$questionId');
            debugPrint('  用户答案: $userAnswers');
            debugPrint('  正确答案: ${q.correctAnswers}');
            debugPrint('  正确数量: $correctCount/${q.blankCount}');
            debugPrint('  得分: ${scores[questionId]}/${q.score}');
          } else {
            // 单空填空题处理
            String answer = userAnswer is String ? userAnswer.trim() : '';
            scores[questionId] = answer.toLowerCase() == q.correctAnswer.toLowerCase() ? q.score : 0;
          }
          break;
          
        case QuestionType.trueOrFalse:
          var q = question as TrueOrFalseQuestion;
          // 判断题答案是布尔值
          bool answer = userAnswer is bool ? userAnswer : false;
          scores[questionId] = answer == q.correctAnswer ? q.score : 0;
          break;
          
        case QuestionType.shortAnswer:
          // 主观题需要人工评分
          // 如果有照片答案，不自动计算得分，等待人工评分
          if (hasPhotoAnswers) {
            // 如果考生上传了图片，不给予任何自动得分，需要管理员人工评分
            scores[questionId] = 0;
            debugPrint('简答题 $questionId 有照片答案，不自动计算得分，等待人工评分');
          } else {
            scores[questionId] = 0;
          }
          break;
      }
    }
    
    return scores;
  }
  
  // 评分逻辑（主观题）
  static void gradeSubjectiveQuestion(String examId, String questionId, int score) {
    // 主观题的评分逻辑（实际应用中应该将分数保存到数据库）
    print('主观题 $questionId 已评分: $score 分');
    
    // 这里可以添加更多持久化存储逻辑
  }

  // 从Excel创建考试 - 空实现
  static Future<Exam?> createExamFromExcel() async {
    debugPrint('此方法已废弃，请使用createExamFromExcelFile');
    return null;
  }

  // 从固定路径Excel创建考试 - 空实现
  static Future<Exam?> createExamFromFixedPathExcel() async {
    debugPrint('此方法已废弃，请使用createExamFromExcelFile');
    return null;
  }

  // 从Excel文件创建考试
  static Future<Exam?> createExamFromExcelFile(
    File excelFile, {
    String? title,
    String? description,
    int? duration,
    String? originalId,
    int? sequence,
  }) async {
    try {
      // 从Excel文件导入题目
      final questions = await ExcelImportService.importQuestionsFromExcelFile(excelFile);
      
      if (questions.isEmpty) {
        debugPrint('从Excel文件导入的题目为空');
        return null;
      }
      
      // 计算总分
      int totalScore = 0;
      for (var question in questions) {
        totalScore += question.score;
      }
      
      // 获取文件名作为默认标题和描述
      String fileName = excelFile.path.split('/').last;
      String fileNameWithoutExt = fileName.contains('.')
          ? fileName.substring(0, fileName.lastIndexOf('.'))
          : fileName;
      
      // 生成稳定的考试ID，基于originalId、sequence和文件名
      String examId;
      if (originalId != null && originalId.isNotEmpty) {
        // 如果有originalId，使用originalId、sequence和文件名生成稳定的ID
        // 这样即使试卷ID相同，不同文件名的试卷也会被区分开
        final fileNameHash = fileNameWithoutExt.hashCode.abs();
        examId = 'exam_${originalId}_${sequence ?? 0}_$fileNameHash';
      } else {
        // 如果没有originalId，使用文件名和题目数量生成稳定的ID
        final fileNameHash = fileNameWithoutExt.hashCode.abs();
        final questionsHash = questions.length;
        examId = 'exam_${fileNameHash}_$questionsHash';
      }

      debugPrint('生成考试ID: $examId (originalId: $originalId, sequence: $sequence)');

      // 创建考试对象
      final exam = Exam(
        id: examId,
        title: title ?? fileNameWithoutExt,
        description: description ?? fileNameWithoutExt,
        duration: duration ?? 60,
        questions: questions,
        totalScore: totalScore,
        originalId: originalId,
        sequence: sequence,
        requirements: [
          "请独立完成考试，不得使用外部资料或帮助",
          "考试时间结束后将自动提交答案",
          "主观题将由教师评分后显示完整结果",
        ],
      );
      
      // 将考试添加到列表中
      await addExam(exam);
      
      return exam;
    } catch (e) {
      debugPrint('从Excel文件创建考试错误: $e');
      return null;
    }
  }

  // 添加新的考试结果
  static Future<bool> addExamResult(ExamResult result) async {
    try {
      if (!_examResults.containsKey(result.examId)) {
        _examResults[result.examId] = [];
      }
      
      // 检查是否已存在相同ID的结果，如果存在则替换
      int existingIndex = _examResults[result.examId]!.indexWhere((r) => r.id == result.id);
      if (existingIndex >= 0) {
        _examResults[result.examId]![existingIndex] = result;
      } else {
        _examResults[result.examId]!.add(result);
      }
      
      // 保存到本地存储
      await _saveExamResultsToStorage();
      
      return true;
    } catch (e) {
      debugPrint('添加考试结果失败: $e');
      return false;
    }
  }
  
  // 更新考试结果（包括照片）
  static Future<bool> updateExamResult(ExamResult result) async {
    try {
      if (!_examResults.containsKey(result.examId)) {
        _examResults[result.examId] = [];
      }
      
      // 查找并更新已有结果
      int existingIndex = _examResults[result.examId]!.indexWhere((r) => r.id == result.id);
      if (existingIndex >= 0) {
        _examResults[result.examId]![existingIndex] = result;
      } else {
        _examResults[result.examId]!.add(result);
      }
      
      // 保存到本地存储
      await _saveExamResultsToStorage();
      
      return true;
    } catch (e) {
      debugPrint('更新考试结果失败: $e');
      return false;
    }
  }
  
  // 获取指定考试的所有结果
  static List<ExamResult> getExamResults(String examId) {
    return _examResults[examId] ?? [];
  }
  
  // 获取特定用户的考试结果
  static ExamResult? getUserExamResult(String examId, String userId) {
    if (!_examResults.containsKey(examId)) {
      return null;
    }
    
    try {
      return _examResults[examId]!.firstWhere((r) => r.userId == userId);
    } catch (e) {
      return null;
    }
  }
  
  // 保存考试结果到本地存储
  static Future<void> _saveExamResultsToStorage() async {
    try {
      final directory = await getApplicationDocumentsDirectory();
      final file = File('${directory.path}/exam_results.json');
      
      // 将结果转换为JSON
      final Map<String, List<Map<String, dynamic>>> jsonData = {};
      _examResults.forEach((examId, results) {
        jsonData[examId] = results.map((r) => r.toJson()).toList();
      });
      
      // 写入文件
      await file.writeAsString(jsonEncode(jsonData));
    } catch (e) {
      debugPrint('保存考试结果到本地存储失败: $e');
    }
  }
  
  // 从本地存储加载考试结果
  static Future<void> _loadExamResultsFromStorage() async {
    try {
      final directory = await getApplicationDocumentsDirectory();
      final file = File('${directory.path}/exam_results.json');
      
      if (await file.exists()) {
        final jsonString = await file.readAsString();
        final Map<String, dynamic> jsonData = jsonDecode(jsonString);
        
        jsonData.forEach((examId, resultsData) {
          final List<dynamic> resultsList = resultsData as List;
          _examResults[examId] = resultsList
              .map((data) => ExamResult.fromJson(data))
              .toList();
        });
      }
    } catch (e) {
      debugPrint('从本地存储加载考试结果失败: $e');
    }
  }

  // 获取可用的考试（考虑试卷ID和序号的唯一性）
  static Exam? getAvailableExamForStudent(String studentId) {
    try {
      // 获取学生已经使用过的试卷ID集合
      Set<String> usedExamIds = {};
      _assignedExams.forEach((examId, studentIds) {
        if (studentIds.contains(studentId)) {
          final exam = getExamById(examId);
          if (exam != null && exam.originalId != null) {
            usedExamIds.add(exam.originalId!);
          }
        }
      });

      // 过滤出学生未使用过试卷ID的考试
      List<Exam> availableExams = _exams.where((exam) {
        // 如果考试没有originalId，使用id
        String examOriginalId = exam.originalId ?? exam.id;

        // 如果学生已经使用过这个试卷ID，则不可用
        if (usedExamIds.contains(examOriginalId)) {
          return false;
        }

        // 如果考试从未被分配，则可用
        if (!_assignedExams.containsKey(exam.id)) {
          return true;
        }

        // 如果考试已分配但未被当前学生使用过，则可用
        return !_assignedExams[exam.id]!.contains(studentId);
      }).toList();

      if (availableExams.isEmpty) {
        return null;
      }

      // 返回第一个可用考试
      return availableExams.first;
    } catch (e) {
      debugPrint('获取可用考试失败: $e');
      return null;
    }
  }

  // 分配考试给学生
  static Future<bool> assignExamToStudent(String examId, String studentId) async {
    try {
      if (!_assignedExams.containsKey(examId)) {
        _assignedExams[examId] = {};
      }
      
      _assignedExams[examId]!.add(studentId);
      
      // 保存分配关系到本地存储
      await _saveAssignedExamsToStorage();
      
      return true;
    } catch (e) {
      debugPrint('分配考试失败: $e');
      return false;
    }
  }

  // 保存已分配的考试到本地存储
  static Future<void> _saveAssignedExamsToStorage() async {
    try {
      final directory = await getApplicationDocumentsDirectory();
      final file = File('${directory.path}/assigned_exams.json');
      
      // 将分配关系转换为JSON
      final Map<String, List<String>> jsonData = {};
      _assignedExams.forEach((examId, studentIds) {
        jsonData[examId] = studentIds.toList();
      });
      
      // 写入文件
      await file.writeAsString(jsonEncode(jsonData));
    } catch (e) {
      debugPrint('保存考试分配关系到本地存储失败: $e');
    }
  }

  // 从本地存储加载已分配的考试
  static Future<void> _loadAssignedExamsFromStorage() async {
    try {
      final directory = await getApplicationDocumentsDirectory();
      final file = File('${directory.path}/assigned_exams.json');
      
      if (await file.exists()) {
        final jsonString = await file.readAsString();
        final Map<String, dynamic> jsonData = jsonDecode(jsonString);
        
        jsonData.forEach((examId, studentIdsData) {
          final List<dynamic> studentIdsList = studentIdsData as List;
          _assignedExams[examId] = Set<String>.from(studentIdsList.map((id) => id.toString()));
        });
      }
    } catch (e) {
      debugPrint('从本地存储加载考试分配关系失败: $e');
    }
  }

  // 生成考试Excel模板
  static Future<String?> generateExamExcelTemplate() async {
    return ExcelImportService.createAndSaveExcelTemplate();
  }
  
  // 为学生随机分配一套考试（考虑试卷ID和序号的唯一性，避免相邻学生分配相同试卷）
  static Exam? getRandomExamForStudent(String studentId) {
    if (_exams.isEmpty) {
      debugPrint('没有可用的考试');
      return null;
    }

    // 获取学生已经使用过的试卷ID集合
    Set<String> usedExamIds = {};
    _assignedExams.forEach((examId, studentIds) {
      if (studentIds.contains(studentId)) {
        final exam = getExamById(examId);
        if (exam != null && exam.originalId != null) {
          usedExamIds.add(exam.originalId!);
        }
      }
    });

    // 过滤出学生未使用过试卷ID的考试
    List<Exam> availableExams = _exams.where((exam) {
      String examOriginalId = exam.originalId ?? exam.id;
      return !usedExamIds.contains(examOriginalId);
    }).toList();

    if (availableExams.isEmpty) {
      debugPrint('学生 $studentId 没有可用的考试（已使用过的试卷ID: $usedExamIds）');
      return null;
    }

    // 如果有超过2套试卷，且有最近分配的试卷记录，则避免分配相同的试卷
    if (availableExams.length > 2 && _lastAssignedExamId != null) {
      // 过滤掉最近分配的试卷
      List<Exam> filteredExams = availableExams.where((exam) {
        return exam.id != _lastAssignedExamId;
      }).toList();

      // 如果过滤后还有可用试卷，使用过滤后的列表
      if (filteredExams.isNotEmpty) {
        availableExams = filteredExams;
        debugPrint('避免相邻学生分配相同试卷，过滤掉最近分配的试卷: $_lastAssignedExamId');
      }
    }

    // 使用学生ID作为随机种子，确保同一学生每次登录得到相同的试题
    final random = Random(studentId.hashCode);
    final randomIndex = random.nextInt(availableExams.length);
    final selectedExam = availableExams[randomIndex];

    // 记录最近分配的试卷ID
    _lastAssignedExamId = selectedExam.id;

    debugPrint('为学生 $studentId 随机分配考试: ${selectedExam.title} (试卷ID: ${selectedExam.originalId}, 序号: ${selectedExam.sequence})');
    debugPrint('更新最近分配的试卷ID: $_lastAssignedExamId');
    return selectedExam;
  }

  // 保存考试数据到本地存储
  static Future<void> _saveExamsToStorage() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final examsJsonString = jsonEncode(_exams.map((exam) => exam.toJson()).toList());
      await prefs.setString(_examsDataKey, examsJsonString);
      debugPrint('考试数据已保存到本地存储，共 ${_exams.length} 个考试');
    } catch (e) {
      debugPrint('保存考试数据到本地存储失败: $e');
    }
  }

  // 从本地存储加载考试数据
  static Future<void> _loadExamsFromStorage() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final examsJsonString = prefs.getString(_examsDataKey);
      
      if (examsJsonString != null) {
        final List<dynamic> examsJson = jsonDecode(examsJsonString);
        _exams.clear();
        _exams.addAll(examsJson.map((json) => Exam.fromJson(json)).toList());
        debugPrint('从本地存储加载了 ${_exams.length} 个考试');
      }
    } catch (e) {
      debugPrint('从本地存储加载考试数据失败: $e');
      _exams.clear();
    }
  }

  // 删除单个考试
  static Future<bool> removeExam(String examId) async {
    try {
      final index = _exams.indexWhere((exam) => exam.id == examId);
      if (index != -1) {
        final removedExam = _exams.removeAt(index);
        await _saveExamsToStorage();
        debugPrint('已删除考试: ${removedExam.title}');
        return true;
      } else {
        debugPrint('未找到要删除的考试: $examId');
        return false;
      }
    } catch (e) {
      debugPrint('删除考试失败: $e');
      return false;
    }
  }

  // 清除所有考试数据（用于重新导入）
  static Future<void> clearAllExams() async {
    try {
      _exams.clear();
      await _saveExamsToStorage();
      debugPrint('已清除所有考试数据');
    } catch (e) {
      debugPrint('清除考试数据失败: $e');
    }
  }

  // 批量清除试卷数据（仅清除试卷，保留考试结果）
  static Future<Map<String, dynamic>> batchClearExams() async {
    try {
      final int examCount = _exams.length;
      final int resultCount = _examResults.values.fold(0, (sum, results) => sum + results.length);
      
      // 清除试卷数据
      _exams.clear();
      
      // 清除分配关系（因为试卷已被清除，分配关系也失效）
      _assignedExams.clear();
      
      // 保存更改
      await _saveExamsToStorage();
      await _saveAssignedExamsToStorage();
      
      debugPrint('批量清除完成：清除了 $examCount 个试卷，保留了 $resultCount 个考试结果');
      
      return {
        'success': true,
        'message': '批量清除成功',
        'details': {
          'clearedExams': examCount,
          'preservedResults': resultCount,
          'summary': '已清除 $examCount 个试卷，保留了 $resultCount 个学生考试结果'
        }
      };
    } catch (e) {
      debugPrint('批量清除试卷失败: $e');
      return {
        'success': false,
        'message': '批量清除失败: $e',
        'details': {
          'clearedExams': 0,
          'preservedResults': 0,
          'summary': '清除操作失败'
        }
      };
    }
  }

  // 获取数据统计信息
  static Map<String, int> getDataStatistics() {
    final int examCount = _exams.length;
    final int resultCount = _examResults.values.fold(0, (sum, results) => sum + results.length);
    final int assignmentCount = _assignedExams.values.fold(0, (sum, assignments) => sum + assignments.length);
    
    return {
      'exams': examCount,
      'results': resultCount,
      'assignments': assignmentCount,
    };
  }
} 